package com.mooc.dao;

import com.mooc.annotation.ColName;
import com.mooc.utils.JdbcUtil;

import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public abstract class BaseDao {
    public <T> T query(String sql, Class newClass, Object... params) {
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        try {
            connection = JdbcUtil.getConnection();
            preparedStatement = connection.prepareStatement(sql);
            for (int i = 0; i < params.length; i++) {
                preparedStatement.setObject(i + 1, params[i]);
            }
            resultSet = preparedStatement.executeQuery();
            while (resultSet.next()) {
                Object object = newClass.newInstance();
                //获取类中的所有属性
                Field[] fields = newClass.getDeclaredFields();
                for (Field field : fields) {
                    //获取注解
                    ColName co = field.getAnnotation(ColName.class);
                    //根据属性名获取数据库中的对应字段的值
                    Object value = resultSet.getObject(co.value());
                    //开启私有属性访问权限
                    field.setAccessible(true);
                    //设置对象中的属性值
                    field.set(object, value);
                }
                return (T) object;
            }
        } catch (SQLException | InstantiationException | IllegalAccessException e) {
            throw new RuntimeException(e);
        } finally {
            JdbcUtil.close(resultSet, preparedStatement, connection);
        }
        return null;
    }

    public <T> List<T> queryList(String sql, Class newClass, Object ...params) {
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        List<T> list=new ArrayList<>();
        try {
            connection = JdbcUtil.getConnection();
            preparedStatement = connection.prepareStatement(sql);
            for (int i = 0; i < params.length; i++) {
                preparedStatement.setObject(i + 1, params[i]);
            }
            resultSet = preparedStatement.executeQuery();
            while (resultSet.next()) {
                Object object = newClass.newInstance();
                //获取类中的所有属性
                Field[] fields = newClass.getDeclaredFields();
                for (Field field : fields) {
                    //获取注解
                    ColName co = field.getAnnotation(ColName.class);
                    //根据属性名获取数据库中的对应字段的值
                    Object value = resultSet.getObject(co.value());
                    //开启私有属性访问权限
                    field.setAccessible(true);
                    //设置对象中的属性值
                    field.set(object, value);
                }
                list.add((T) object);
            }
            return list;
        } catch (SQLException | InstantiationException | IllegalAccessException e) {
            throw new RuntimeException(e);
        } finally {
            JdbcUtil.close(resultSet, preparedStatement, connection);
        }
    }

    public <T> T queryCompoundList(String sql, Class newClass, Object... params) {
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        List<T> list=new ArrayList<>();
        try {
            connection = JdbcUtil.getConnection();
            preparedStatement = connection.prepareStatement(sql);
            for (int i = 0; i < params.length; i++) {
                preparedStatement.setObject(i + 1, params[i]);
            }
            resultSet = preparedStatement.executeQuery();
            while (resultSet.next()) {
                Object object = newClass.newInstance();
                //获取类中的所有属性
                Field[] fields = newClass.getDeclaredFields();
                for (Field field : fields) {
                    field.setAccessible(true);
//                    Class<?> innerObjectClass = field.get(object).getClass();
//                    Object inObject=innerObjectClass.newInstance();
//                    Field[] innerField = innerObjectClass.getDeclaredFields();
                        Field[] innerField = field.get(object).getClass().getDeclaredFields();

                        for (Field inField : innerField) {
                            //获取注解
                            ColName co = inField.getAnnotation(ColName.class);
                            //根据属性名获取数据库中的对应字段的值
                            Object value = resultSet.getObject(co.value());
                            //开启私有属性访问权限
                            inField.setAccessible(true);
                            //设置对象中的属性值
                            inField.set(field.get(object), value);
                        }
                }
                list.add((T) object);
            }
            return (T) list;
        } catch (SQLException | InstantiationException | IllegalAccessException e) {
            throw new RuntimeException(e);
        } finally {
            JdbcUtil.close(resultSet, preparedStatement, connection);
        }
    }

    public <T> boolean insert(String sql, Object... params) {
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        try {
            connection = JdbcUtil.getConnection();
            preparedStatement = connection.prepareStatement(sql);
            for (int i = 0; i < params.length; i++) {
                preparedStatement.setObject(i + 1, params[i]);
            }
            int i = preparedStatement.executeUpdate();
            if (i > 0) {
                return true;
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            JdbcUtil.close(preparedStatement, connection);
        }
        return false;
    }
    public <T> boolean update(String sql, Object... params){
        Connection connection=null;
        PreparedStatement preparedStatement=null;
        try{
            connection = JdbcUtil.getConnection();
            preparedStatement=connection.prepareStatement(sql);
            for (int i = 0; i < params.length; i++) {
                preparedStatement.setObject(i + 1, params[i]);
            }
            int result= preparedStatement.executeUpdate();
            if (result==1){
                return true;
            }
            return false;

        } catch (SQLException e) {
            throw new RuntimeException(e);
        }finally {
            JdbcUtil.close(preparedStatement,connection);
        }
    }

    public <T> int count(String sql, Object... params) {
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        int fileCount = 0;
        try {
            connection = JdbcUtil.getConnection();
            preparedStatement = connection.prepareStatement(sql);
            for (int i = 0; i < params.length; i++) {
                preparedStatement.setObject(i + 1, params[i]);
            }
            resultSet = preparedStatement.executeQuery();
            if (resultSet.next()) {
                fileCount = resultSet.getInt(1);
            }
            return fileCount;
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            JdbcUtil.close(resultSet, preparedStatement, connection);
        }
    }

    public  boolean delete(String sql, Object ...params) {
        Connection connection=null;
        PreparedStatement preparedStatement=null;
        try{
            connection = JdbcUtil.getConnection();
            preparedStatement=connection.prepareStatement(sql);
            for (int i = 0; i < params.length; i++) {
                preparedStatement.setObject(i + 1, params[i]);
            }
            int result= preparedStatement.executeUpdate();
            if (result==1){
                return true;
            }
            return false;

        } catch (SQLException e) {
            throw new RuntimeException(e);
        }finally {
            JdbcUtil.close(preparedStatement,connection);
        }
    }

//    public void close(ResultSet resultSet, PreparedStatement preparedStatement, Connection connection) {
//        if (resultSet != null) {
//            try {
//                resultSet.close();
//            } catch (SQLException e) {
//                throw new RuntimeException(e);
//            }
//        }
//        if (preparedStatement != null) {
//            try {
//                preparedStatement.close();
//            } catch (SQLException e) {
//                throw new RuntimeException(e);
//            }
//        }
//        if (connection != null) {
//            try {
//                connection.close();
//            } catch (SQLException e) {
//                throw new RuntimeException(e);
//            }
//        }
//    }
//
//    public void close(PreparedStatement preparedStatement, Connection connection) {
//        if (preparedStatement != null) {
//            try {
//                preparedStatement.close();
//            } catch (SQLException e) {
//                throw new RuntimeException(e);
//            }
//        }
//        if (connection != null) {
//            try {
//                connection.close();
//            } catch (SQLException e) {
//                throw new RuntimeException(e);
//            }
//        }
//    }

}
